package com.xgry.bpm.api.business.model.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xgry.bpm.api.base.createtable.entity.CreateTable;
import com.xgry.bpm.api.base.createtable.service.CreateTableService;
import com.xgry.bpm.api.base.formlist.entity.FormList;
import com.xgry.bpm.api.base.formlist.service.FormListService;
import com.xgry.bpm.api.base.formltem.service.FormLtemService;
import com.xgry.bpm.api.base.sqlservice.service.SqlService;
import com.xgry.bpm.api.base.tableclass.entity.TableClass;
import com.xgry.bpm.api.base.tableclass.service.TableClassService;
import com.xgry.bpm.api.business.defaultfield.entity.DefaultField;
import com.xgry.bpm.api.business.defaultfield.service.DefaultFieldService;
import com.xgry.bpm.api.business.model.entity.Model;
import com.xgry.bpm.api.business.model.form.ModelForm;
import com.xgry.bpm.api.business.model.service.ModelService;
import com.xgry.bpm.api.business.model.vo.ModelVO;
import com.xgry.bpm.api.business.modelclass.service.ModelClassService;
import com.xgry.bpm.common.utils.EasyPoiUtils;
import com.xgry.bpm.common.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;


/**
 * <p>
 * Model前端控制器
 *
 * </p>
 *
 * @author admin
 * @since 2020-07-16
 */
@RestController
@Api(tags = "Model")
@RequestMapping("/model")
public class ModelController {

    @Autowired
    private ModelService modelService;

    @Autowired
    private TableClassService tableClassService;

    @Autowired
    private DefaultFieldService defaultFieldService;

    @Autowired
    private CreateTableService createTableService;

    @Autowired
    private FormListService formListService;

    @Autowired
    private FormLtemService formLtemService;

    @Autowired
    private SqlService sqlService;

    @Autowired
    private JdbcTemplate jdbcTemplate;
    /**
     * 保存单条
     *
     * @param param 保存参数
     * @return 是否添加成功
     */
    @ApiOperation(value = "保存", notes = "保存数据到Model")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "code", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "modelName", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "modelClassId", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "uuid", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "creatPerson", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "createDate", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "createPName", value = "${field.comment}", required = false),
            @ApiImplicitParam(paramType = "query", name = "processId", value = "${field.comment}", required = false),
    })
    @RequestMapping(value = "/insertModel.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result addModel(@RequestBody ModelForm param) throws Exception {

        List<Model> queryList = modelService.list(new QueryWrapper<Model>() {{
            this.and(s -> s.eq("modelName", param.getModelName()).or().eq("code", param.getCode()));
        }});

        if (!CollectionUtils.isEmpty(queryList)) {
            return Result.fail("模型名称或模型编号已存在！请重新输入！");
        }

        modelService.save(param);

        TableClass tableClass = new TableClass();
        tableClass.setTableClassName(param.getClassName());
        tableClass.setTableChClassName(param.getClassChName());
        tableClass.setDbInfoId(param.getDbInfoId());
        tableClass.setPid(param.getPid());
        tableClass.setModelId(param.getId());
        tableClassService.save(tableClass);

        ArrayList<CreateTable> createTables = new ArrayList<>();
        for (DefaultField defaultField : defaultFieldService.list()) {
            CreateTable createTable = new CreateTable();
            createTable.setTableClassId(tableClass.getTableClassId());
            createTable.setTableName(tableClass.getTableClassName());
            if ("parent_level".equals(defaultField.getFieldName())) {
                createTable.setField(defaultField.getFieldName());
            }else {
                createTable.setField(tableClass.getTableClassName() + "_" + defaultField.getFieldName());
            }
            createTable.setState("1");
            createTable.setState("1");
            createTable.setFieldCh(defaultField.getFieldChName());
            createTable.setType(defaultField.getFieldType());
            createTable.setFileTypeCh(defaultField.getFieldType());
            createTables.add(createTable);
        }
        createTableService.saveBatch(createTables);

        JSONObject createTable = new JSONObject();
        JSONObject dataJson = new JSONObject();
        dataJson.put("cTableName" , param.getClassName());
        dataJson.put("dbinfo_id",param.getDbInfoId());
        createTable.put("data", dataJson);
        sqlService.createTable(createTable);
        return Result.success();
    }

    /**
     * 删除(根据主键id删除)
     *
     * @param //主键id
     *
     *  逻辑：
     *
     * @return 是否删除成功
     */
    @ApiOperation(value = "删除数据", notes = "根据主键id删除Model数据")
    @ApiImplicitParam(paramType = "query", name = "", value = "Id", required = true, dataType = "String")
    @RequestMapping(value = "/deleteModel.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    @Transactional
    public Result deleteModelById(@RequestParam("modelId") Integer modelId) {

        List<TableClass> tableClasses = tableClassService.findByModelId(modelId);
        List<FormList> formLists = formListService.findByModelId(modelId);

        for (FormList formList : formLists) {
            formLtemService.deleteByFormListId(formList.getFormListId());
            formListService.removeById(formList.getFormListId());
        }

        for (TableClass tableClass : tableClasses) {
            createTableService.deleteByTableId(tableClass.getTableClassId());
            jdbcTemplate.update("DROP TABLE "+tableClass.getTableClassName());
            tableClassService.removeById(tableClass);
        }

        modelService.deleteById(modelId);
        return Result.success("操作成功");
    }


    /**
     * 更新(根据主键id更新)
     *
     * @param param 修改参数
     * @return 是否更改成功
     */
    @ApiOperation(value = "更新数据", notes = "根据主键id更新Model数据")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "code", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelClassId", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "uuid", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "creatPerson", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createDate", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createPName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "processId", value = "${field.comment}", required = false, dataType = ""),
    })
    @RequestMapping(value = "/updateById.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result updateModelById(@RequestBody ModelForm param) {
        if (1 != modelService.updateById(param)) {
            return Result.fail("保存失败");
        }
        return Result.success();
    }




    /**
     * 根据主键id查询单条
     *
     * @param // 主键id
     * @return 查询结果
     */
    @ApiOperation(value = "获取单条数据", notes = "根据主键id获取Model数据")
    @ApiImplicitParam(paramType = "query", name = "", value = "Id", required = true, dataType = "String")
    @RequestMapping(value = "/getById.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result getModelById(@RequestParam(value = "Id") String id) {
        ModelVO result = modelService.selectById(id);
        if (null == result) {
            return Result.fail("无数据！");
        }
        return Result.success("操作成功", result);
    }

    @ApiOperation(value = "获取单条数据", notes = "根据主键id获取Model数据")
    @ApiImplicitParam(paramType = "query", name = "", value = "modelClassId", required = true, dataType = "String")
    @PostMapping(value = "/findByModelClassId.do")
    public Result findByModelClassId(@RequestParam("modelClassId")Integer modelClassId){
        return Result.success(modelService.findByModelClassId(modelClassId));
    }

    @ApiOperation(value = "获取单条数据", notes = "根据主键id获取Model数据")
    @ApiImplicitParam(paramType = "query", name = "", value = "code", required = true, dataType = "String")
    @PostMapping(value = "/findByCode.do")
    public Result findByCode(@RequestParam("code")Integer code){
        List<ModelVO> queryModelCode = modelService.findByModelCode(code);
        if (!CollectionUtils.isEmpty(queryModelCode)) {
            Result.success(HttpStatus.SC_METHOD_FAILURE,"code已存在，请重新输入");
        }
        return Result.success("验证成功");
    }

    @ApiOperation(value = "获取单条数据", notes = "根据主键id获取Model数据")
    @ApiImplicitParam(paramType = "query", name = "", value = "code", required = true, dataType = "String")
    @PostMapping(value = "/findByModelName.do")
    public Result findByModelName(@RequestParam("modelName")String modelName){
        List<ModelVO> queryModelCode = modelService.findByModelName(modelName);
        if (!CollectionUtils.isEmpty(queryModelCode)) {
            Result.success(HttpStatus.SC_METHOD_FAILURE,"模型名称已存在，请重新输入");
        }
        return Result.success("验证成功");
    }




    /**
     * 查询全部
     *
     * @param //param 查询条件
     * @return 查询结果
     */
    @ApiOperation(value = "全部查询", notes = "查询Model全部数据")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "code", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelClassId", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "uuid", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "creatPerson", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createDate", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createPName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "processId", value = "${field.comment}", required = false, dataType = ""),
    })
    @RequestMapping(value = "/queryAll.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result getModelAll(@RequestBody ModelForm param) {
        List<ModelVO> result = modelService.selectAll(param);
        if (CollectionUtils.isEmpty(result)) {
            return Result.fail("无数据！");
        }
        return Result.success("操作成功", result);
    }

    /**
     * 分页查询
     *
     * @param //param 查询条件
     * @return 查询结果
     */
    @ApiOperation(value = "分页查询", notes = "分页查询Model全部数据")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "code", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "modelClassId", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "uuid", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "creatPerson", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createDate", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "createPName", value = "${field.comment}", required = false, dataType = ""),
            @ApiImplicitParam(paramType = "query", name = "processId", value = "${field.comment}", required = false, dataType = ""),
    })
    @RequestMapping(value = "/queryPage.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result getModelPage(@RequestBody ModelForm param) {
        IPage<ModelVO> result = modelService.selectPage(param);
        if (CollectionUtils.isEmpty(result.getRecords())) {
            return Result.fail("无数据！");
        }
        return Result.convertIpageToSuccess(result);
    }

    /**
     * Excel导入
     *
     * @param //param 查询条件
     * @return 查询结果
     */
    @ApiOperation(value = "Excel导入", notes = "导入全字段")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "", value = "", required = false, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "", value = "", required = false, dataType = "String")
    })
    @RequestMapping(value = "/importExcel.do", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public Result importExcel(@RequestParam MultipartFile file) throws Exception {
        List<Model> list = EasyPoiUtils.importExcel(file, 0, 1, Model.class);
        if (CollectionUtils.isEmpty(list)) {
            return Result.fail("无数据");
        }
        return Result.success();
    }

    /**
     * Excel导出
     *
     * @param //param 查询条件
     * @return 查询结果
     */
    @ApiOperation(value = "Excel导出", notes = "导出全字段")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "current", value = "页码", required = false, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "size", value = "每页条数", required = false, dataType = "String")

    })
    @RequestMapping(value = "/exportExcel.do", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8"})
    public void exportExcel(HttpServletResponse response) throws Exception {
        List<Model> result = modelService.list();
        EasyPoiUtils.exportExcel(result, "列表", "报表", Model.class, "明细报表.xls", response);
    }


}

